#ifndef _SM4_H_
#define _SM4_H_

//加解密模式
typedef enum {
    SM4_MODE_ECB = 0,   // 电子密码本模式
    SM4_MODE_CBC = 1,   // 密码块连接模式
    SM4_MODE_CFB = 2,   // 密文反馈模式 
    SM4_MODE_OFB = 3,   // 输出反馈模式 
    SM4_MODE_CTR = 4,   // 计数器模式   
} SM4Mode_t;

//填充方式
typedef enum {
    SM4_NoPadding = 0,  
    SM4_Zeros = 1,      
    SM4_ISO10126 = 2,   
    SM4_PKCS7 = 3,      
} SM4Padding_t;

/**
 * \brief          SM4 context structure
 */
typedef struct
{
    int mode;                   /* 加密模式 关联 SM4Mode_t*/
    int padding;                /* 填充方式 关联 SM4Padding_t */
    unsigned char iv[16];       /* 初始化向量 */
    unsigned long sk[32];       /* SM4 subkeys */
    unsigned long skd[32];       /* SM4 subkeys decode*/
    void (*ctr_alg)(void *Nonce, int counter);  /* MODE_CTR模式下使用的算法 */
}sm4_context;


#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief sm4 init function
 * 
 * @param ctx SM4 context
 * @param mode sm4 encode mode, 
 * @param padding sm4 filling type
 * @param key sm4 key, it must be 16 bytes data
 * @param iv sm4 iv, it must be 16 bytes data
 * @param alg MODE_CTR will use this personal algorithm
 */
void sm4_init( sm4_context *ctx, SM4Mode_t mode, SM4Padding_t padding, unsigned char key[16], unsigned char iv[16], void (*alg)(void*,int));

/**
 * @brief sm4 encrypt function
 * 
 * @param ctx SM4 context
 * @param input the data that need to be encrypt
 * @param length input data length
 * @param output output the encrypted data, it need at least length+16 bytes size
 * @return int - output data length, return 0 means fail
 */
int sm4_encrypt( sm4_context *ctx, unsigned char *input, int length, unsigned char *output);

/**
 * @brief sm4 decrypt function
 * 
 * @param ctx SM4 context
 * @param input the data that need to be decrypt
 * @param length input data length
 * @param output output the decrypted data, it need at least length bytes size
 * @return int - output data length, return 0 means fail
 */
int sm4_decrypt( sm4_context *ctx, unsigned char *input, int length, unsigned char *output);

#ifdef __cplusplus
}
#endif

#endif /* _SM4_H_ */
